package main.items.wallet

import main.models.StateAction
import main.person.Person
import main.state.{State, StateLens}

case class TransferMoneyAction(
    fromPerson: StateLens[Person],
    toPerson: StateLens[Person],
    amount: Int
) extends StateAction {

  def getWallet(state: State, person: StateLens[Person]): StateLens[Wallet] = {
    val walletLens = state.ownershipTree.findNode(person).get.children
      .find(a => a.value.isInstanceOf[StateLens[Wallet]])

    println(state.ownershipTree.findNode(person).get.children.head.value.get(state))

    walletLens match {
      case Some(wallet) => wallet.value.asInstanceOf[StateLens[Wallet]]
      case _ => throw TransferMoneyException("Person doesn't have a wallet")
    }
  }

  override def apply(implicit state: State): State = {
    val walletFrom = getWallet(state, fromPerson)
    val walletTo = getWallet(state, toPerson)
    if(walletFrom.get.balance < amount) throw TransferMoneyException("Sufficient balance")

    val updated1State = fromPerson.removeChild(state, walletFrom)
    val (newWalletFrom, updated2State) = updated1State.registerEntity(Wallet(walletFrom.get.balance - amount))
    val updated3State = fromPerson.addChild(updated2State, newWalletFrom)

    val updated4State = toPerson.removeChild(updated3State, walletTo)
    val (newWalletTo, updated5State) = updated4State.registerEntity(Wallet(walletTo.get.balance + amount))
    toPerson.addChild(updated5State, newWalletTo)

  }
}

case class TransferMoneyException(message: String) extends Exception(message)